package com.mowh.multithreading.read.write.lock;

/**
 * @author mowh1gd
 * @create 2023/11/21 16:53
 */
public class ReadWriteLock {//扮演读写锁（是逻辑锁，开发人员实现的一种结构，与实例持有的物理锁不一样，实现逻辑锁的物理锁只有一个，即实例持有的物理锁）
    private int readingReaders = 0;
    private int waitingWriters = 0;
    private int writingWriters = 0;
    private boolean preferWriter = true;

    public synchronized void readLock() throws InterruptedException {
        while (writingWriters > 0 || (preferWriter && waitingWriters > 0)) {//读时非守护条件：即读时如果有写线程，或等待的写线程数大于0而且写优先，则读线程全部进入等待。
            wait();
        }
        readingReaders++;//读时守护条件为writingWriters<=0，即读时不能有写线程。
    }
    public synchronized void readUnlock() {
        readingReaders--;//线程已经读完，线程数要减1
        preferWriter = true;//设置写优先
        notifyAll();
    }
    public synchronized void writeLock() throws InterruptedException {
        waitingWriters++;//为了模拟写线程的等待，等待写线程数加1。
        try {
            while (readingReaders > 0 || writingWriters > 0) {//写时非守护条件：即写时如果已经有读线程，或已经有写线程，则该写线程进入等待。
                wait();
            }
        } finally {
            waitingWriters--;//写线程等待完毕后，等待写线程数减1。
        }
        writingWriters++;//写时守护条件为readingReaders<=0&&writingWriters<=0，即写时不能有其它读与写线程。
    }
    public synchronized void writerUnlock() {
        writingWriters--;//线程已经写完，线程数要减1
        preferWriter = false;//设置读优先
        notifyAll();
    }
}
